<script setup>
  import * as THREE from "three";
  import { onMounted, ref } from "vue";
  import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
  import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
  import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
  let controls;
  let canvasDom = ref(null);
  // 创建场景
  const scene = new THREE.Scene();
  // 创建相机
  const camera = new THREE.PerspectiveCamera(
    75,
    window.innerWidth / window.innerHeight,
    0.1,
    1000
  );
  camera.position.set(0, 2, 6);
  // 创建渲染器
  const renderer = new THREE.WebGLRenderer({
    // 抗锯齿
    antialias: true,
  });
  renderer.setSize(window.innerWidth, window.innerHeight);

  const render = () => {
    renderer.render(scene, camera);
    controls && controls.update();
    requestAnimationFrame(render);
  };

  let wheels = [];
  let carParts = {
    body: null,
    front: null,
    hood: null,
    glass: null,
    wheels: []
  };

  // 颜色列表
  const colorList = [
    { name: "红色", value: 0xff0000 },
    { name: "蓝色", value: 0x0000ff },
    { name: "绿色", value: 0x00ff00 },
    { name: "灰色", value: 0x808080 },
    { name: "橙色", value: 0xffa500 },
    { name: "紫色", value: 0x800080 },
    { name: "黑色", value: 0x000000 },
    { name: "白色", value: 0xffffff }
  ];

  // 材质列表
  const materialList = [
    { name: "磨砂", clearcoat: 0.3, roughness: 0.8, clearcoatRoughness: 0.9 },
    { name: "金属", clearcoat: 1, roughness: 0.4, clearcoatRoughness: 0.1 },
    { name: "哑光", clearcoat: 0, roughness: 0.7, clearcoatRoughness: 0.2 },
    { name: "镜面", clearcoat: 1, roughness: 0.1, clearcoatRoughness: 0 }
  ];

  // 汽车各部位材质
  let partMaterials = {
    body: new THREE.MeshPhysicalMaterial({
      color: 0xff0000,
      metalness: 1,
      roughness: 0.5,
      clearcoat: 1,
      clearcoatRoughness: 0,
    }),
    front: new THREE.MeshPhysicalMaterial({
      color: 0xff0000,
      metalness: 1,
      roughness: 0.5,
      clearcoat: 1,
      clearcoatRoughness: 0,
    }),
    hood: new THREE.MeshPhysicalMaterial({
      color: 0xff0000,
      metalness: 1,
      roughness: 0.5,
      clearcoat: 1,
      clearcoatRoughness: 0,
    }),
    wheels: new THREE.MeshPhysicalMaterial({
      color: 0x000000,
      metalness: 1,
      roughness: 0.1,
    }),
    glass: new THREE.MeshPhysicalMaterial({
      color: 0xffffff,
      metalness: 0,
      roughness: 0,
      transmission: 1,
      transparent: true,
    })
  };

  // 当前选中的部位
  let selectedPart = ref('all');
  // 当前选中的材质
  let selectedMaterial = ref(1);

  // 选择颜色
  let selectColor = (colorIndex) => {
    const color = colorList[colorIndex].value;

    if (selectedPart.value === 'all' || selectedPart.value === 'body') {
      partMaterials.body.color.set(color);
    }
    if (selectedPart.value === 'all' || selectedPart.value === 'front') {
      partMaterials.front.color.set(color);
    }
    if (selectedPart.value === 'all' || selectedPart.value === 'hood') {
      partMaterials.hood.color.set(color);
    }
    if (selectedPart.value === 'all' || selectedPart.value === 'wheels') {
      partMaterials.wheels.color.set(color);
    }
    if (selectedPart.value === 'all' || selectedPart.value === 'glass') {
      partMaterials.glass.color.set(color);
    }
  };

  // 选择材质
  let selectMaterial = (materialIndex) => {
    selectedMaterial.value = materialIndex;
    const material = materialList[materialIndex];

    if (selectedPart.value === 'all' || selectedPart.value === 'body') {
      partMaterials.body.clearcoat = material.clearcoat;
      partMaterials.body.roughness = material.roughness;
      partMaterials.body.clearcoatRoughness = material.clearcoatRoughness;
    }
    if (selectedPart.value === 'all' || selectedPart.value === 'front') {
      partMaterials.front.clearcoat = material.clearcoat;
      partMaterials.front.roughness = material.roughness;
      partMaterials.front.clearcoatRoughness = material.clearcoatRoughness;
    }
    if (selectedPart.value === 'all' || selectedPart.value === 'hood') {
      partMaterials.hood.clearcoat = material.clearcoat;
      partMaterials.hood.roughness = material.roughness;
      partMaterials.hood.clearcoatRoughness = material.clearcoatRoughness;
    }
  };

  // 选择汽车部位
  let selectPart = (part) => {
    selectedPart.value = part;
  };

  onMounted(() => {
    // 把渲染器插入到dom中
    canvasDom.value.appendChild(renderer.domElement);
    // 初始化渲染器，渲染背景
    renderer.setClearColor("#000");
    scene.background = new THREE.Color("#1a1a2e");
    scene.environment = new THREE.Color("#1a1a2e");
    render();

    // 添加网格地面
    const gridHelper = new THREE.GridHelper(10, 10);
    gridHelper.material.opacity = 0.2;
    gridHelper.material.transparent = true;
    scene.add(gridHelper);

    // 添加控制器
    controls = new OrbitControls(camera, renderer.domElement);
    controls.update();

    // 添加gltf汽车模型
    const loader = new GLTFLoader();
    const dracoLoader = new DRACOLoader();
    dracoLoader.setDecoderPath("./draco/gltf/");
    loader.setDRACOLoader(dracoLoader);
    loader.load("./model/bmw01.glb", (gltf) => {
      const bmw = gltf.scene;

      bmw.traverse((child) => {
        if (child.isMesh) {
          // 判断是否是轮毂
          if (child.name.includes("轮毂")) {
            child.material = partMaterials.wheels;
            carParts.wheels.push(child);
          }
          // 判断是否是车身
          if (child.name.includes("Mesh002")) {
            carParts.body = child;
            carParts.body.material = partMaterials.body;
          }
          // 判断是否是前脸
          if (child.name.includes("前脸")) {
            carParts.front = child;
            carParts.front.material = partMaterials.front;
          }
          // 判断是否是引擎盖
          if (child.name.includes("引擎盖_1")) {
            carParts.hood = child;
            carParts.hood.material = partMaterials.hood;
          }
          // 判断是否是挡风玻璃
          if (child.name.includes("挡风玻璃")) {
            carParts.glass = child;
            carParts.glass.material = partMaterials.glass;
          }
        }
      });
      scene.add(bmw);
    });

    // 添加灯光
    const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
    scene.add(ambientLight);

    const light1 = new THREE.DirectionalLight(0xffffff, 1);
    light1.position.set(0, 10, 10);
    scene.add(light1);

    const light2 = new THREE.DirectionalLight(0xffffff, 0.5);
    light2.position.set(-10, 10, 0);
    scene.add(light2);

    const light3 = new THREE.DirectionalLight(0xffffff, 0.3);
    light3.position.set(0, -10, 0);
    scene.add(light3);

    // 添加环境光
    const hemisphereLight = new THREE.HemisphereLight(0xffffff, 0x888888, 0.3);
    scene.add(hemisphereLight);

    // 窗口大小改变时更新渲染器
    window.addEventListener('resize', () => {
      camera.aspect = window.innerWidth / window.innerHeight;
      camera.updateProjectionMatrix();
      renderer.setSize(window.innerWidth, window.innerHeight);
    });
  });
</script>
<template>
  <div class="home">
    <div
      class="canvas-container"
      ref="canvasDom"
    ></div>

    <div class="home-content">
      <div class="home-content-title">
        <h1>3D汽车展示与个性化定制</h1>
      </div>

      <!-- 部位选择 -->
      <h2>选择汽车部位</h2>
      <div class="select">
        <div
          class="select-item part-item"
          v-for="(part, index) in [{ name: '全部', value: 'all' }, { name: '车身', value: 'body' }, { name: '前脸', value: 'front' }, { name: '引擎盖', value: 'hood' }, { name: '轮毂', value: 'wheels' }, { name: '玻璃', value: 'glass' }]"
          :key="index"
          @click="selectPart(part.value)"
          :class="{ active: selectedPart === part.value }"
        >
          <div class="select-item-text">{{ part.name }}</div>
        </div>
      </div>

      <!-- 颜色选择 -->
      <h2>选择颜色</h2>
      <div class="select">
        <div
          class="select-item"
          v-for="(color, index) in colorList"
          :key="index"
          @click="selectColor(index)"
          :title="color.name"
        >
          <div
            class="select-item-color"
            :style="{ backgroundColor: '#' + color.value.toString(16).padStart(6, '0') }"
          ></div>
        </div>
      </div>

      <!-- 材质选择 -->
      <h2>选择贴膜材质</h2>
      <div class="select">
        <div
          class="select-item material-item"
          v-for="(material, index) in materialList"
          :key="index"
          @click="selectMaterial(index)"
          :class="{ active: selectedMaterial === index }"
        >
          <div class="select-item-text">{{ material.name }}</div>
        </div>
      </div>
    </div>
  </div>
</template>
<style>
  * {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
  }

  body {
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
  }

  .canvas-container {
    width: 100vw;
    height: 100vh;
    overflow: hidden;
  }

  .home-content {
    position: fixed;
    top: 20px;
    right: 20px;
    background: rgba(255, 255, 255, 0.9);
    backdrop-filter: blur(10px);
    padding: 20px;
    border-radius: 15px;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
    max-width: 300px;
    z-index: 1000;
  }

  .home-content-title h1 {
    font-size: 20px;
    color: #333;
    margin-bottom: 20px;
    text-align: center;
  }

  h2 {
    font-size: 16px;
    color: #555;
    margin: 20px 0 10px 0;
  }

  .select {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-bottom: 15px;
  }

  .select-item {
    cursor: pointer;
    transition: transform 0.2s ease, box-shadow 0.2s ease;
  }

  .select-item:hover {
    transform: translateY(-2px);
    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
  }

  .select-item-color {
    width: 40px;
    height: 40px;
    border: 2px solid #ddd;
    border-radius: 8px;
    transition: border-color 0.2s ease;
  }

  .select-item-color:hover {
    border-color: #999;
  }

  .select-item-text {
    padding: 8px 12px;
    background: #f0f0f0;
    border-radius: 8px;
    font-size: 14px;
    color: #333;
    font-weight: 500;
  }

  .part-item.active .select-item-text,
  .material-item.active .select-item-text {
    background: #4a90e2;
    color: white;
  }

  @media (max-width: 768px) {
    .home-content {
      position: fixed;
      top: auto;
      bottom: 0;
      right: 0;
      left: 0;
      max-width: none;
      border-radius: 15px 15px 0 0;
      padding: 15px;
    }

    .select {
      justify-content: center;
    }

    .select-item-color {
      width: 35px;
      height: 35px;
    }
  }
</style>